﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "ComponentEditorGnufUI.h"
#include "ElementId.h"
#include "GnufItemEvents.h"
#include "IDrawingViewportEventHandler.h"
#include "IElementsChangeEventHandler.h"
#include "ITransactionEventHandler.h"
#include "IUiDocumentEventHandler.h"
#include "IUiViewEventHandler.h"
#include "IUndoRedoEventHandler.h"

namespace gnuf {
    class TreeBoard;
    class TreeNode;
    class ContextMenu;
    class DragMove;
}

namespace gcmp {
    class IUiView;
    class IDocument;
    class IUiDocument;
    class IModelView;
    class CommandParameters;
}

namespace gfam 
{
    class ExplorerBlockManager;
    class COMPONENT_EDITOR_GNUF_UI_EXPORT GnufModelViewBoardHandler
    {
    public:
        virtual ~GnufModelViewBoardHandler() {}
        virtual void onDetailListItemDbClicked(const gcmp::ElementId& modelViewId) {}
    };

    // replace BmModelViewDialog
    class COMPONENT_EDITOR_GNUF_UI_EXPORT GnufModelViewBoard final
        : public gnuf::IItemEventHandler
        , public gcmp::IUiDocumentEventHandler
        , public gcmp::IUiViewEventHandler
        , public gcmp::IUndoRedoEventHandler
        , public gcmp::ITransactionEventHandler
        , public gcmp::IElementsChangeEventHandler
        , public gcmp::IDrawingViewportEventHandler
    {
    public:
        GnufModelViewBoard();
        virtual ~GnufModelViewBoard() { m_handlers.clear(); }

    public:
        // 初始化视图资源管理器（注册事件）
        void Initialize(gnuf::TreeBoard*);

        // 用缓存的UiDoc刷新资源管理器根节点下的所有内容
        void Refresh();

        // 激活当前视图
        void ActivateView(gcmp::ElementId modelViewId);

    private:
        // Inherits from IUiDocumentEventHandler
        virtual void On(gcmp::IUiDocumentEventArgs* pArgs) override;

        // Inherits from IUiViewEventHandler
        virtual void On(gcmp::IUiViewEventArgs* pArgs) override;

        // Inherits from IUndoRedoEventHandler
        virtual void On(gcmp::IUndoRedoEventArgs* pArgs) override;

        // Inherits from ITransactionEventHandler
        virtual void On(gcmp::ITransactionEventArgs* pArgs) override;

        // Inherits from IElementsChangeEventHandler
        virtual void On(gcmp::IElementsChangeEventArgs* pArgs) override;

        // Inherits from IDrawingViewportEventHandler
        virtual void On(gcmp::IDrawingViewportEventArgs* pArgs) override;

    private:
        // Inherits from gnuf::IItemEventHandler...
        virtual void onTreeItemDbClicked(gnuf::TreeNode*) override;
        virtual void onTreeItemRButtonClicked(gnuf::TreeNode*, int x, int y) override;
        virtual bool onKeyDown(gnuf::Item* item, int key, bool, bool, bool, bool) override;
        virtual void onCurrentIndexChanged(gnuf::ContextMenu *) override;
        virtual bool onDragOff(gnuf::TreeNode*) override;
        virtual void onDrop(gnuf::TreeNode*) override;

        void SetAllItemsExpandedStatus(gnuf::TreeNode* pParentItem, bool expandStatus);

    private:

        //在视图管理器界面上高亮所设视图
        virtual void HighlightSelectedModelView(gcmp::IDocument *pDoc, const gcmp::IUiView* pUIView);

        bool GetSelectedViewPort(gcmp::IDocument *pDoc, gcmp::ElementId &selectedId);
        const gcmp::IModelView* GetCurModelView();

        void AttachEventHandler(gcmp::IUiDocument* pUIDoc);
        void DetachEventHandler(gcmp::IUiDocument* pUIDoc);

        void UpdateFamilyTreeItemContextMenu(gnuf::TreeNode* selectedItem);

        void CreateFamilyInstance();
        void RenameFamily();
        void EditFamily();
        void LoadFamily();
        void LoadSubFamily();
        void SaveAsFamily();
        void RemoveFamily();
        void RemoveImportedObject();
        void RemoveSelectedModelView();
        void GetProjectModelViewData(const gcmp::ElementId& modelViewId);

        //设置视图命令参数
        void SetModelViewCommandParameters(gcmp::IModelView* pModelView,gcmp::CommandParameters &cmdParams);

    private:
        template<class Func>
        void notify(const Func& func)
        {
            for (auto& handler : m_handlers)
            {
                if (handler) func(handler);
            }
        }

    private:
        gnuf::TreeBoard* m_tree;
        int m_uiDocId;      // ui文档Id
        bool m_isNeedUpdate; // 是否需要更新(用于连续修改延时更新）
        bool m_bShowFamilyManagementMenuItem; // 是否在族右键时显示菜单

                                              // 绑定到族树右键菜单的命令
        std::wstring m_cmdIdCreateFamilyInstance;
        std::wstring m_cmdIdRenameFamily;
        std::wstring m_cmdIdEditFamily;
        std::wstring m_cmdIdLoadFamily;
        std::wstring m_cmdIdLoadSubFamily;
        std::wstring m_cmdIdSaveAsFamily;
        std::wstring m_cmdIdRemoveFamily;
        std::wstring m_cmdIdRemoveImportedObject;

        gcmp::OwnerPtr<gnuf::ContextMenu> m_contextMenu;
        std::set<GnufModelViewBoardHandler*> m_handlers;
    };
}